;; -*- lisp -*-

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; load path
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(add-to-list 'load-path "~/cedet/")
(add-to-list 'load-path "~/ecb/")
(add-to-list 'load-path "~/auto-complete/")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; customize variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; All customized variables should come here! As if there is more than one,
;; they won't work right.
; .No startup screen
; .Show all files in speedbar
; .Fix the shit message which ecb always gives at emacs startup
; .Fix ecb side window/buffer size
; .Set the side window/buffer size
(custom-set-variables
 '(inhibit-startup-screen t)
 '(speedbar-show-unknown-files t)
 '(ecb-options-version "2.40")
 '(ecb-fix-window-size t)
 '(ecb-windows-width 30))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Emacs general looking config
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; No tool bar
(tool-bar-mode nil)

;; no backup~ files
(setq make-backup-files nil)

;; Enable column line number mode
(setq column-number-mode t)

;; Enable line high light and set the color
(global-hl-line-mode t)
(set-face-background hl-line-face "yellow")

;; Full screen for X window on linux
(if (eq system-type 'gnu/linux)
	(defun toggle-fullscreen ()
	  (interactive)
	  (x-send-client-message nil 0 nil "_NET_WM_STATE" 32
							 '(2 "_NET_WM_STATE_MAXIMIZED_VERT" 0))
	  (x-send-client-message nil 0 nil "_NET_WM_STATE" 32
							 '(2 "_NET_WM_STATE_MAXIMIZED_HORZ" 0))
	  )
  )
;; Full screen for X window on linux
(if (eq system-type 'gnu/linux)
	(if window-system
		(toggle-fullscreen)
	  )
  )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Global key binding
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Execute a shell command in minibuffer
(global-set-key [f12] 'shell-command)

;; Flash a buffer after it is changed outside emacs
(defun revert-buffer-no-confirm()
  "Revert buffer without confirmation."
  (interactive) (revert-buffer t t))
;; Flash a buffer after it is changed outside emacs
(global-set-key [f5] 'revert-buffer-no-confirm)

;; Copy, I don't know why \M-w doesn't work on windows
(global-set-key "\M-w" 'copy-region-as-kill)

;; Enlarge and shrink window
(global-set-key [(control ?+)] 'enlarge-window)
(global-set-key [(control ?=)] 'shrink-window)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; gdb
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; gdb many windows mode
(setq gdb-many-windows t)
(setq gdb-use-separate-io-buffer nil)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; c/c++ programming language style
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Use c style for cl, td, def ... programs
(add-to-list 'auto-mode-alist '("\\.cl\\'" . c-mode))
(add-to-list 'auto-mode-alist '("\\.td\\'" . c++-mode))
(add-to-list 'auto-mode-alist '("\\.def\\'" . c-mode))

;; Set default c style to linux style
(setq c-default-style "linux"
	  c-basic-offset 4)

;; Set default table indent to 4
(setq-default tab-width 4)
(setq indent-line-function 'insert-tab)

;; switch/case: m11ake each case line indent from switch
(c-set-offset 'case-label '+)

;; make the ENTER key indent next line properly
(global-set-key "\C-m" 'newline-and-indent)

;syntax highlight
(global-font-lock-mode 1)
(setq font-lock-maximum-decoration t)
(custom-set-faces)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Auto-complete
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/auto-complete/ac-dict")
(ac-config-default)

;; Implement a semantic-complete-self-insert like command
(defun ac-complete-semantic-self-insert (arg)
  (interactive "p")
  (self-insert-command arg)
  (ac-complete-semantic))

;; M-p, M-n, Tab navigate between candidates
;; RET choose the highlight candidate

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; CEDET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Load CEDET
(load-file "~/cedet/common/cedet.el")

(require 'cedet)
(require 'eieio-opt)
(require 'ede)
(require 'ede-locate)
(require 'semantic-load)

;; gcc setup
(require 'semantic-gcc)
(semantic-gcc-setup)

;; Enable advanced functionality for name completion, etc.
(require 'semantic-ia)

(setq semantic-load-turn-everything-on t)

;; Enable gaudy semantic (code-parsing, smart completion) features
(semantic-load-enable-gaudy-code-helpers)
;; (semantic-load-enable-excessive-code-helpers)
;; (semantic-load-enable-semantic-debugging-helpers)

;; Code template manager
(global-srecode-minor-mode 1)

;; Integration with imenu
(defun my-semantic-hook()
  (imenu-add-to-menubar "TAGS"))
(add-hook 'semantic-init-hooks 'my-semantic-hook)

;; Bind some major semantic features for better use.
(defun my-cedet-hook()
  ;; Show all condidates completion in a seperate buffer
  ;;(local-set-key [(control return)] 'semantic-ia-complete-symbol)
  ;; Pop up a menu for all candidates completion
  (local-set-key [(control tab)] 'semantic-ia-complete-symbol-menu)
  ;; Switch between function prototype and definition
  (local-set-key "\M-gp" 'semantic-analyze-proto-impl-toggle)
  ;;(local-set-key "." 'semantic-complete-self-insert)
  ;;(local-set-key ">" 'semantic-complete-self-insert)
  ;; Use ac-complete instead of semantic
  (local-set-key "." 'ac-complete-semantic-self-insert)
  (local-set-key ">" 'ac-complete-semantic-self-insert)
  (local-set-key "\M-gd" 'semantic-ia-fast-jump)
  )
(add-hook 'c-mode-common-hook 'my-cedet-hook)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ecb - emacs code browser,  requires full cedet
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(require 'ecb)

;; No version check for cedet
(setq ecb-version-check nil)

;; No ecb tip of the day showing at startup
(setq ecb-tip-of-the-day nil)

;; Customize ecb window
;; ecb-set-directories-buffer
;; ecb-set-sources-buffer
;; ecb-set-methods-buffer
;; ecb-set-history-buffer
;; ecb-set-speedbar-buffer
;; ecb-set-analyse-buffer
;; ecb-set-symboldef-buffer
(ecb-layout-define "aries-layout" left nil
   ;; The frame is already splitted side by side and point stays in the
   ;; right window (= the ECB-tree-window-column)

   ;; Here is the creation code for the new layout

   ;; Define the current window/buffer as speedbar buffer
   (ecb-set-speedbar-buffer)
   ;; Splitting the ECB-tree-window-column in two windows
   (ecb-split-ver 0.4 t)
   ;; Go to the second window
   (other-window 1)
   ;; Define the current windows/buffer as Methods buffer
   (ecb-set-methods-buffer)
   ;; Splitting the second window into two windows
   ;;(ecb-split-ver 0.7 t)
   ;; Goto the third window
   ;;(other-window 1)
   ;; Define the current window as History buffer
   ;;(ecb-set-history-buffer)
   ;; Make the ECB-edit-window current (see Postcondition above)
   (select-window (next-window)))

(setq ecb-layout-name "aries-layout")

;; Keyboard shortcut for ecb navigating
(global-set-key [f2] 'ecb-goto-window-speedbar)
(global-set-key [f3] 'ecb-goto-window-methods)
(global-set-key [f4] 'ecb-goto-window-history)
(global-set-key [f6] 'ecb-goto-window-edit1) ;left edit window
(global-set-key [f7] 'ecb-goto-window-edit2) ;right edit window
(global-set-key [f8] 'ecb-goto-window-edit-last) ;last edit window

;; Hide and show ecb window
(global-set-key [(f9)] 'ecb-toggle-ecb-windows)

;; Active ecb now
;;(setq ecb-auto-activate t)
(ecb-activate)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; EDE - project management
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Enable EDE
(global-ede-mode 1)

;; Projects, enabling by define the variable to 1
(defvar rogue_dev 0)
(defvar rogue_main 0)
(defvar llvm      0)

;; Common varible for rogue development
(setq TOOLCHAIN "/usr/local/i686-refpci-linux-gnu-gcc-4.2.4-glibc-2.7")

;; Project rogue_dev
(setq ROGUEDDK_DEV "~/p4/hualin.wu_opencl_dev_ws/powervr/swgraphics/rogueddk/DEV/opencl_dev")
(if (eq rogue_dev 1)
	(ede-cpp-root-project "OpenCL DEV"
					:name "IMG OpenCL DEV Driver"
					:file (concat ROGUEDDK_DEV "/Makefile")
					:include-path '( (concat ROGUEDDK_DEV "/include")
									 (concat ROGUEDDK_DEV "/hwdefs")
									 (concat ROGUEDDK_DEV "/common")
									 (concat ROGUEDDK_DEV "/opencl")
									 (concat ROGUEDDK_DEV "/tools/intern/llvmufgen")
									 )
					:system-include-path '((concat TOOLCHAIN "/include")
										   (concat ROGUEDDK_DEV "/include/khronos/OCL/CL12")
										   )
					:spp-table '(("BUILD" . "debug")
								 ("EXCLUDED_APIS" . "opengl opengles1 opengles3")
								 ("PDUMP" . "1")
								 )
					)
  )

;; Project rogue_main
(setq ROGUEDDK_MAIN  "~/p4/hualin.wu_opencl_dev_ws/powervr/swgraphics/rogueddk/MAIN")
(if (eq rogue_main 1)
	(ede-cpp-root-project "OpenCL MAIN"
					:name "IMG OpenCL MAIN Driver"
					:file (concat ROGUEDDK_MAIN "/Makefile")
					:include-path '( (concat ROGUEDDK_MAIN "/include")
									 (concat ROGUEDDK_MAIN "/opencl")
									 (concat ROGUEDDK_MAIN "/tools/intern/llvmufgen")
									 )
					:system-include-path '((concat TOOLCHAIN "/include")
										   (concat ROGUEDDK_MAIN "/include/khronos/OCL/CL12")
										   )
					:spp-table '(("BUILD" . "debug")
								 ("EXCLUDED_APIS" . "opengl opengles1 opengles3")
								 ("PDUMP" . "1")
								 )
					)
  )

;; Project llvm
(setq LLVM_ROOT "d:/llvm")
(if (eq llvm 1)
	(ede-cpp-root-project "LLVM"
					:name "llvm development"
					:file (concat LLVM_ROOT "/Makefile")
					:include-path '( (concat LLVM_ROOT "/include")
									 )
;;					:system-include-path '((concat TOOLCHAIN "/include")
;;										   )
					:spp-table '(("LLVM_BUILD" . "debug")
								 )
					)
  )
	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Other setup
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;; Only enable cscope for linux.
;; cscope - cross reference for c/c++
;; Include cscope.el, you need to apt-get install cscope.el first.
;;(if (eq system-type 'gnu/linux)
;;	(require 'xcscope)
;;)

;; Reference:
;; 1. a Chinese guy's .emacs: http://blog.csdn.net/ericzhong83/article/details/4509887
;; 2. cedet config: http://alexott.net/en/writings/emacs-devenv/EmacsCedet.html
